/*
Copyright (C) 2015 Marien Raat, Jochem Raat

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <SFML/Graphics.hpp>

#include <random>
#include <string>
#include <vector>

#include <islandHeightmapGenerator.h>
#include <markovNames.h>
#include <landMap.h>
#include <waterGenerator.h>
#include <windMap.h>
#include <heatMap.h>
#include <groundWaterMap.h>
#include <biomeGenerator.h>
#include <renderedMap.h>

#include <button.h>
#include <textBox.h>
#include <progressWindow.h>

#if defined(_WIN32) || defined(WIN32) || defined(__WIN32__)
#define OS_WIN
#endif

enum ViewType {
    HEIGHTMAP,
    RIVER_MAP,
    WIND_MAP,
    HEAT_MAP,
    GROUND_WATER_MAP,
    BIOME_MAP,
    RENDERED_MAP
};

class GUIFrontend {
public:
    GUIFrontend();
    void start();
private:
    bool loadFiles();
    void handleEvents();
    void draw();
    void drawGUI();
    void drawProgress(std::string text, float peruntage);

    void pushBackHistory(unsigned);
    void pushForwardHistory(unsigned);
    unsigned popBackHistory();
    unsigned popForwardHistory();
    void clearForwardHistory();
    void goBack();
    void goForward();

    unsigned getRandomSeed();
    int getSeedFromClipboard(); // returns -1 if it fails
    void setSeed(unsigned seed);
    void copySeedToClipboard(unsigned seed);

    void generateNew();
    void generateNewWithSeed(unsigned seed);
    void generateWithSeed(unsigned seed);

    void save();

    void fillImage(double *values, sf::Image *image);

    bool mapGenerated;

    sf::Vector2u islandSize;
    sf::RenderWindow *window;

    // Logo
    sf::Texture logoTexture;
    sf::Sprite logoSprite;

    // GUI
    sf::Font buttonFont;
    sf::Texture buttonTexture, clickedButtonTexture,
        navButtonTexture, navButtonClickedTexture,
        copyButtonTexture, copyButtonClickedTexture;
    ViewType currentView;

    // Randomness
#ifndef OS_WIN
    std::random_device *randomDevice;
#endif
    std::mt19937 *mt;

    // The history of seeds to the left
    std::vector<unsigned> backHistory;

    // The current seed
    unsigned currentSeed;
    // The current name
    std::string currentName;

    // The history of seeds to the right:
    std::vector<unsigned> forwardHistory;


    // Text Box
    TextBox *seedBox, *nameBox;

    // Buttons
    Button *backButton, *forwardButton,
        *copyButton, *pasteButton,
        *generateButton, *saveButton,
        *heightmapButton, *riverMapButton,
        *windMapButton, *heatMapButton,
        *groundWaterMapButton, *biomeButton,
        *renderedMapButton;

    // Progress
    ProgressWindow *progressWindow;

    // Generators
    IslandHeightmapGenerator *islandHeightmapGenerator;
    MarkovNames *markovNames;
    LandMapGenerator *landMapGenerator;
    WaterGenerator *waterGenerator;
    WindMapGenerator *windMapGenerator;
    HeatMapGenerator *heatMapGenerator;
    GroundWaterMapGenerator *groundWaterMapGenerator;
    BiomeGenerator *biomeGenerator;
    RenderedMapGenerator *renderedMapGenerator;

    // Images
    sf::Image heightmapImage;
    sf::Image riverMapImage;
    sf::Image windMapImage;
    sf::Image heatMapImage;
    sf::Image groundWaterMapImage;
    sf::Image biomeMapImage;
    sf::Image renderedMapImage;

    // Textures
    sf::Texture heightmapTexture;
    sf::Texture riverMapTexture;
    sf::Texture windMapTexture;
    sf::Texture heatMapTexture;
    sf::Texture groundWaterMapTexture;
    sf::Texture biomeMapTexture;
    sf::Texture renderedMapTexture;

    sf::Sprite displaySprite;
};
